#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <wchar.h>
#include <sys/ioctl.h>

#include <fonts_manager.h>

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <wchar.h>
#include <sys/ioctl.h>

#include <fonts_manager.h>


static int fd_hzk16;
static struct stat hzk_stat;
static unsigned char *hzkmem;


static int hzk_FontInit(char *FontFileName, int FontSize)
{
    fd_hzk16 = open(FontFileName, O_RDONLY);
    if (fd_hzk16 < 0)
    {
        printf("Can't open hzk\n");
        return -1;
    }

    if (fstat(fd_hzk16, &hzk_stat) < 0)
    {
        printf("Can't get fstat\n");
        close(fd_hzk16);
        return -1;
    }

    hzkmem = (unsigned char *)mmap(NULL, hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);
    if (hzkmem == MAP_FAILED)
    {
        printf("Can't mmap for hzk\n");
        close(fd_hzk16);
        return -1;
    }

    return 0;
}


static int hzk_GetFontBitmap(unsigned int dwCode, PFontBitMap ptFontBitMap)
{
    int iPenX = ptFontBitMap->iCurOriginX;
    int iPenY = ptFontBitMap->iCurOriginY;

    unsigned char high = (dwCode >> 8) & 0xFF;
    unsigned char low  = dwCode & 0xFF;

    // 判断 dwCode 是否在 hzk 范围内
    if (high < 0xA1 || high > 0xF7 || low < 0xA1 || low > 0xFE)
    {
        printf("unsupported hzk code: 0x%x\n", dwCode);
        return -1;
    }

    int area  = high - 0xA1;  // 第几区（0-based）
    int index = low - 0xA1;   // 区内第几个字（0-based）
    size_t offset = (area * 94 + index) * 32;  // 每个汉字占32字节（16×16点阵）

    // 防止越界：dwCode的末端指针不能超过字库文件的总大小
    if (offset + 32 > hzk_stat.st_size)
    {
        printf("offset out of bounds\n");
        return -1;
    }

    ptFontBitMap->iXLeft  = iPenX;
    ptFontBitMap->iYTop   = iPenY - 16;
    ptFontBitMap->iXMax   = iPenX + 16;
    ptFontBitMap->iYMax   = iPenY;
    ptFontBitMap->iBpp    = 1;
    ptFontBitMap->iPitch  = 2;  // 每行占 2 字节（16 像素）
    ptFontBitMap->iNextOriginX = iPenX + 16;
    ptFontBitMap->iNextOriginY = iPenY;
    ptFontBitMap->pucBuffer = hzkmem + offset;

    return 0;
}




static FontOpr hzk_FontOpr = {
    .name = "hzk",
    .FontInit = hzk_FontInit,
    .GetFontBitmap = hzk_GetFontBitmap,
};




void Registerhzk(void)
{
    RegisterFontOpr(&hzk_FontOpr);
}